package cn.com.nes.site.service.crm.clue.impl;

import cn.com.nes.common.exception.BusinessException;
import cn.com.nes.common.util.Globals;
import cn.com.nes.common.util.HttpUtils;
import cn.com.nes.common.util.OssUtil;
import cn.com.nes.common.util.XzqhUtils;
import cn.com.nes.common.util.id.IdUtils;
import cn.com.nes.mybatis.agent.crm.entity.Clue;
import cn.com.nes.mybatis.agent.crm.entity.LogOperate;
import cn.com.nes.mybatis.agent.crm.mapper.ClueMapper;
import cn.com.nes.site.controller.crm.clue.vo.CluePageVo;
import cn.com.nes.site.entity.em.DeleteEnum;
import cn.com.nes.site.entity.em.crm.clue.ClueClaimTypeEnum;
import cn.com.nes.site.entity.em.crm.clue.ClueDistributeStateEnum;
import cn.com.nes.site.entity.em.crm.clue.ClueStageEnum;
import cn.com.nes.site.entity.em.crm.customer.CustomerNatureEnum;
import cn.com.nes.site.entity.vo.crm.GetClueDetailVO;
import cn.com.nes.site.entity.vo.crm.SaveUpdateClueVo;
import cn.com.nes.site.service.crm.clue.CrmClueService;
import cn.com.nes.site.service.crm.clue.bo.ClueBO;
import cn.com.nes.site.service.crm.clue.bo.ClueSaveBO;
import cn.com.nes.site.service.crm.clue.dto.*;
import cn.com.nes.site.service.crm.log.LogOperateService;
import cn.com.nes.site.service.thirdapi.PhoneOwnershipLocationAPI;
import cn.com.nes.site.service.thirdapi.dto.PhoneOwnershipLocationDTO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.net.URLDecoder;
import java.util.*;

@Slf4j
@Service
public class CrmClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements CrmClueService {

    @Resource
    private LogOperateService logOperateService;

    /**
     * 线索分页列表
     * @param vo
     * @return
     */
    @Override
    public Page<ClueDTO> getCluePage(CluePageVo vo) throws Exception {
        Page<ClueDTO> page = new Page<>(vo.getPageid(), vo.getPagesize());
        if (!Globals.DEMO_COMPANYID.equals(vo.getOperateUserCompanyId())) {//不是演示账号
            if (!"04".equals(vo.getUserInfo().getUserType())) {//不是管理员公海不加线索，我的客户自己看自己的
                vo.setXzqhdms(XzqhUtils.splitRegionCodes(vo.getUserInfo().getAreacode()));
            }
        }
        if ("mine".equals(vo.getType())) {
            vo.setQuyClueOwner(String.valueOf(vo.getOperateUserId()));
        }

        // 获取行政区划查询参数
        vo.setXzqhdm(XzqhUtils.getRegionCodePrefix(vo.getXzqhdm()));
        List<ClueDTO> clueList = this.baseMapper.getClueListPage(page, vo);
        clueList.forEach(clueDTO -> {
            clueDTO.setCustomerNatureName(CustomerNatureEnum.getEnum(clueDTO.getCustomerNature()).getValue());
            clueDTO.setIsFp(StrUtil.isNotEmpty(clueDTO.getClueOwner()));
        });
        page.setRecords(clueList);
        return page;
    }

    /**
     * 新增/更新线索
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveUpdateClue(SaveUpdateClueVo vo) throws Exception {
        boolean clueUuid = StrUtil.isEmpty(vo.getUuid());

        String id;
        if (clueUuid) {
            parameJudgment(vo);
            id = saveClue(vo);
            saveOperateLog(id, vo, "新增客户");
        } else {
            id = updateClue(vo);
            saveOperateLog(id, vo, "修改客户");
        }
        return id;
    }

    /**
     * 线索详情
     * @param vo
     * @return
     */
    @Override
    public Map<String, Object> getClueDetail(GetClueDetailVO vo) throws Exception {
        // 准备返回值
        Map<String, Object> extData = new LinkedHashMap<>();

        // 查询线索主体信息
        ClueDetailDTO clueDetail = this.baseMapper.getClueDetailByUuid(vo);
        if (Objects.isNull(clueDetail)) {
            throw new BusinessException("线索详情不存在!");
        }
        clueDetail.setCustomerNatureName(CustomerNatureEnum.getEnum(clueDetail.getCustomerNature()).getValue());
        clueDetail.setIsFp(vo.getUserInfo().getCompanyId().equals(clueDetail.getClueBelongToCompany()));
        // 查询订单信息
        if (StrUtil.isNotBlank(clueDetail.getProductId())) {
            String storeName = this.baseMapper.getStoreName(clueDetail.getProductId());
            clueDetail.setStoreName(storeName);
        }
        // 查询线索列表
        List<ClueSourceDetailDTO> clueSourceList = this.baseMapper.getClueSourceList(vo.getUuid(), vo.getUserInfo()
                .getCompanyId()); // 不使用热链云公司id
        clueDetail.setSourceList(clueSourceList);
        // 获取线索图片
        setClueImg(clueDetail);

        // 返回值组装线索信息
        log.info("线索主体信息: {}", JSON.toJSONString(clueDetail));
        extData.put("clueInfo", clueDetail);

        // 查询跟进列表
        List<GetClueFollowUpDTO> followUpList = this.baseMapper.getFollowUpList(vo.getUuid());
        log.info("线索跟进信息: {}", JSON.toJSONString(followUpList));
        extData.put("visitList", followUpList);

        // 查询商机列表
        List<GetClueBusinessDTO> businessList = this.baseMapper.getBusinessList(vo.getUuid());
        log.info("线索商机信息: {}", JSON.toJSONString(businessList));
        extData.put("opportunityList", businessList);

        return extData;
    }

    /**
     * 线索保存
     * @param clueBO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Clue clueSave(ClueBO clueBO) throws Exception {
        Clue clue = buildClue(clueBO);
        this.saveOrUpdate(clue);

        logOperateService.saveLogOperate(logOperateService.buildLogOperate(clueBO));
        return clue;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Clue saveClue(ClueBO clueBO) throws Exception {
        // 如果参数没有手机号，直接创建线索
        if (StrUtil.isBlank(clueBO.getClueSaveBO().getCluePhone())) {
            return this.clueSave(clueBO);
        }
        // 根据手机号查询是否已经存在线索
        QueryWrapper<Clue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cluephone", clueBO.getClueSaveBO().getCluePhone());
        queryWrapper.eq("cluebelongtocompany", clueBO.getOperateUserCompanyId());
        queryWrapper.eq("isdelete", String.valueOf(DeleteEnum._0.getKey()));
        queryWrapper.last("limit 1");
        List<Clue> clues = this.baseMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(clues)) {
            return clues.get(0);
        }
        // 没有已存在的线索,创建新的线索
        return this.clueSave(clueBO);
    }

    private @NotNull Clue buildClue(ClueBO clueBO) {
        Clue clue;
        ClueSaveBO clueSaveBO = clueBO.getClueSaveBO();
        if (clueBO.isAdd()) {
            clue = new Clue();
            clue.setUuid(IdUtils.uuid());
            clue.setCreateTime(clueBO.getOperateDate());
            clue.setCreateUid(clueBO.getOperateUserId());
            clue.setClueBelongToCompany(clueBO.getOperateUserCompanyId());
            clue.setDeleted(DeleteEnum._0.getKey());
            PhoneOwnershipLocationDTO phoneOwnershipLocation = PhoneOwnershipLocationAPI.getPhoneOwnershipLocation(clueSaveBO.getCluePhone());
            if (ObjectUtil.isNotNull(phoneOwnershipLocation)) {
                clue.setNumberHome(phoneOwnershipLocation.getProvince() + phoneOwnershipLocation.getCity());
            }

            clueBO.getClueSaveBO().setUuid(clue.getUuid());
        } else {
            clue = this.getById(clueSaveBO.getUuid());
        }
        if (ClueClaimTypeEnum.CLAIM.equals(clueSaveBO.getClaimType())) {
            clue.setClueOwner(clueSaveBO.getClueOwnerId());
            clue.setCuleState(ClueDistributeStateEnum.DISTRIBUTE.getKey());
        } else {
            clue.setCuleState(ClueDistributeStateEnum.NO_DISTRIBUTE.getKey());
        }
        clue.setModifyTime(clueBO.getOperateDate());
        clue.setModifyUid(clueBO.getOperateUserId());

        clue.setClueName(clueSaveBO.getClueName());
        clue.setClueCompany(clueSaveBO.getClueName());
        clue.setCompanyContact(clueSaveBO.getClueContact());
        clue.setCluePhone(clueSaveBO.getCluePhone());
        clue.setXzqhdm(StrUtil.isEmpty(clueSaveBO.getAreaCode()) ? null : clueSaveBO.getAreaCode());
        clue.setCustomerAddress(clueSaveBO.getClueAddress());
        clue.setLatitude(clueSaveBO.getLatitude());
        clue.setLongitude(clueSaveBO.getLongitude());
        clue.setSex(clueSaveBO.getGender());

        clue.setClueStage(clueSaveBO.getClueStage().getKey());
        clue.setFollowupStatus(clueSaveBO.getFollowUpStatus().getKey());
        clue.setPoolEntryMode(clueSaveBO.getPoolEntryMode().getKey());
        clue.setCustomerNature(clueSaveBO.getCustomerNature().getKey());
        clue.setClueSource(clueSaveBO.getClueSource());
        clue.setAdvertisementId(clueSaveBO.getActiveOrAdvertisementUuid());
        clue.setBusinessDirection(clueSaveBO.getBusinessDirection());
        clue.setMemo(clueSaveBO.getClueMemo());

        try {
            clue.setJsonData(URLDecoder.decode(clueSaveBO.getJsonData(), "UTF-8"));
        } catch (Exception e) {
            log.error("线索保存，模版字段异常，{}", e.getMessage());
        }
        return clue;
    }

    //新增
    private String saveClue(SaveUpdateClueVo vo) throws Exception {
        Clue clue = vo.convertToClue();
        clue.setUuid(UUID.randomUUID().toString());
        if (StrUtil.isEmpty(clue.getPoolEntryMode())) {
            clue.setPoolEntryMode("05");//录入
        }
        clue.setJsonData(URLDecoder.decode(clue.getJsonData(), "UTF-8"));
        this.baseMapper.insert(clue);
        return clue.getUuid();
    }

    //修改
    private String updateClue(SaveUpdateClueVo vo) throws Exception {
        Clue clue = vo.convertToClue();
        clue.setJsonData(URLDecoder.decode(clue.getJsonData(), "UTF-8"));
        this.baseMapper.updateById(clue);
        return clue.getUuid();
    }

    // 保存操作记录
    private void saveOperateLog(String clueId, SaveUpdateClueVo vo, String remark) {
        Clue clue = this.baseMapper.selectById(clueId);

        LogOperate logOperate = new LogOperate();
        logOperate.setUuid(UUID.randomUUID().toString());
        logOperate.setClueid(clueId);
        logOperate.setCustomerid(clue.getCustomerId());
        logOperate.setCreatetime(clue.getModifyTime());
        logOperate.setUserid(String.valueOf(vo.getOperateUserId()));
        logOperate.setUsername(vo.getOperateUserName());
        logOperate.setCompanyid(vo.getOperateUserCompanyId());
        logOperate.setMemo(vo.getUserInfo()
                .getCompanyName() + " " + vo.getOperateUserName() + "修改了 " + clue.getCompanyContact() + " 客户");
        logOperate.setType("02");
        logOperate.setRemark(remark);
        logOperateService.save(logOperate);
    }

    //参数判断
    private void parameJudgment(SaveUpdateClueVo vo) throws Exception {
        String cluephone = vo.getCluePhone();
        String oldcluephone = vo.getOldCluePhone();
        Map<String, String> obj = HttpUtils.getPhoneAddress(cluephone);
        String areaBelong = obj.get("city") + obj.get("province");
        vo.setNumberHome(areaBelong);
        //如果企业联系人手机号更换，则将原来联系人手机号所有的线索都换成新手机号
        if (!cluephone.equals(oldcluephone)) {
            this.baseMapper.updatePhone(vo);
        }

        String clueStage = vo.getClueStage();
        if (StrUtil.isEmpty(clueStage) || ClueStageEnum.NEW.getKey().equals(clueStage)) {
            vo.setClueStage("01");
            vo.setFollowupStatus("01");
        } else if (StrUtil.isNotEmpty(clueStage) || ClueStageEnum.CLEAR_INTENTION.getKey().equals(clueStage)) {
            vo.setFollowupStatus("02");
        }
        //拓展字段用
        if (StrUtil.isNotEmpty(vo.getJsonData())) {
            vo.setJsonData(URLDecoder.decode(vo.getJsonData(), "UTF-8"));
        }
        if ("1".equals(vo.getIsRl())) {
            vo.setCuleState("01");
            vo.setClueOwner(vo.getUserInfo().getId());
        } else {
            vo.setCuleState("02");
        }
    }

    // 查询图片信息
    private void setClueImg(ClueDetailDTO clueDetail) {
        if (StrUtil.isNotBlank(clueDetail.getPicture1())) {
            //压缩
            String imgReal = OssUtil.getImgSignURL(clueDetail.getPicture1(), 1);
            clueDetail.setImgReal1(imgReal);
            //不压缩
            String imgRealBig = OssUtil.getImgSignURL(clueDetail.getPicture1(), 0);
            clueDetail.setImgRealBig1(imgRealBig);
        }
        if (StrUtil.isNotBlank(clueDetail.getPicture2())) {
            //压缩
            String imgReal = OssUtil.getImgSignURL(clueDetail.getPicture2(), 1);
            clueDetail.setImgReal2(imgReal);
            //不压缩
            String imgRealBig = OssUtil.getImgSignURL(clueDetail.getPicture2(), 0);
            clueDetail.setImgRealBig2(imgRealBig);
        }
        if (StrUtil.isNotBlank(clueDetail.getPicture3())) {
            //压缩
            String imgReal = OssUtil.getImgSignURL(clueDetail.getPicture3(), 1);
            clueDetail.setImgReal3(imgReal);
            //不压缩
            String imgRealBig = OssUtil.getImgSignURL(clueDetail.getPicture3(), 0);
            clueDetail.setImgRealBig3(imgRealBig);
        }
    }

}
